#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
文件转换核心模块
实现各种文件格式之间的转换功能
"""

import os
import sys
import subprocess
import tempfile
from pathlib import Path
import shutil

# 导入转换库
try:
    from docx import Document
    from docx2pdf import convert as docx2pdf_convert
except ImportError:
    Document = None
    docx2pdf_convert = None

try:
    import pandas as pd
    from openpyxl import Workbook
except ImportError:
    pd = None
    Workbook = None

try:
    from pptx import Presentation
except ImportError:
    Presentation = None

try:
    import PyPDF2
    from fpdf import FPDF
    from reportlab.pdfgen import canvas
    from reportlab.lib.pagesizes import letter, A4
    from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    from reportlab.pdfbase import pdfmetrics
    from reportlab.pdfbase.ttfonts import TTFont
    from reportlab.lib.fonts import addMapping
except ImportError:
    PyPDF2 = None
    FPDF = None
    canvas = None
    letter = None
    A4 = None
    SimpleDocTemplate = None
    Paragraph = None
    Spacer = None
    getSampleStyleSheet = None
    ParagraphStyle = None
    pdfmetrics = None
    TTFont = None
    addMapping = None

try:
    import markdown
except ImportError:
    markdown = None

try:
    from weasyprint import HTML, CSS
except ImportError:
    HTML = None
    CSS = None

try:
    from ebooklib import epub
    import zipfile
    import xml.etree.ElementTree as ET
except ImportError:
    epub = None
    zipfile = None
    ET = None

try:
    import chardet
    import requests
except ImportError:
    chardet = None
    requests = None

try:
    from striprtf.striprtf import rtf_to_text
except ImportError:
    rtf_to_text = None

# 图像处理库
try:
    from PIL import Image, ImageSequence
    import pillow_heif
    pillow_heif.register_heif_opener()
except ImportError:
    Image = None
    ImageSequence = None
    pillow_heif = None

try:
    import cv2
except ImportError:
    cv2 = None

try:
    import cairosvg
except (ImportError, OSError):
    cairosvg = None

try:
    import rawpy
except ImportError:
    rawpy = None

try:
    from pdf2image import convert_from_path
except ImportError:
    convert_from_path = None

# 音频处理库
try:
    import librosa
    import soundfile as sf
except ImportError:
    librosa = None
    sf = None

try:
    from pydub import AudioSegment
    from pydub.utils import which
except ImportError:
    AudioSegment = None
    which = None

try:
    import ffmpeg
except ImportError:
    ffmpeg = None


class FileConverter:
    """文件转换器类"""
    
    def __init__(self):
        self._setup_chinese_fonts()
        self.supported_conversions = {
            "DOC/DOCX → PDF": self.docx_to_pdf,
            "DOC/DOCX → ODT": self.docx_to_odt,
            "XLS/XLSX → PDF": self.xlsx_to_pdf,
            "XLS/XLSX → ODS": self.xlsx_to_ods,
            "PPT/PPTX → PDF": self.pptx_to_pdf,
            "PPT/PPTX → ODP": self.pptx_to_odp,
            "PDF → TXT": self.pdf_to_txt,
            "RTF → DOCX": self.rtf_to_docx,
            "RTF → TXT": self.rtf_to_txt,
            "EPUB → MOBI": self.epub_to_mobi,
            "EPUB → PDF": self.epub_to_pdf,
            "MOBI → EPUB": self.mobi_to_epub,
            "MOBI → PDF": self.mobi_to_pdf,
            "AZW3 → EPUB": self.azw3_to_epub,
            "HTML → PDF": self.html_to_pdf,
            "Markdown → HTML": self.markdown_to_html,
            "Markdown → DOCX": self.markdown_to_docx,
            "Markdown → PDF": self.markdown_to_pdf,
            # 图像转换功能
            "JPG/JPEG → PNG": self.jpg_to_png,
            "JPG/JPEG → WEBP": self.jpg_to_webp,
            "PNG → JPG/JPEG": self.png_to_jpg,
            "PNG → WEBP": self.png_to_webp,
            "WEBP → JPG/JPEG": self.webp_to_jpg,
            "WEBP → PNG": self.webp_to_png,
            "GIF → PNG": self.gif_to_png,
            "GIF → WEBP": self.gif_to_webp,
            "BMP → JPG": self.bmp_to_jpg,
            "BMP → PNG": self.bmp_to_png,
            "TIFF → JPG": self.tiff_to_jpg,
            "TIFF → PNG": self.tiff_to_png,
            "RAW → JPG": self.raw_to_jpg,
            "RAW → PNG": self.raw_to_png,
            "RAW → TIFF": self.raw_to_tiff,
            "RAW → DNG": self.raw_to_dng,
            "SVG → PDF": self.svg_to_pdf,
            "SVG → PNG": self.svg_to_png,
            "SVG → JPG": self.svg_to_jpg,
            "PDF → JPG": self.pdf_to_jpg,
            "PDF → PNG": self.pdf_to_png,
            "HEIC → JPG/JPEG": self.heic_to_jpg,
            "HEIC → PNG": self.heic_to_png,
            "GIF_EXTRACT_ALL_FRAMES": self.gif_extract_all_frames,
            # 音频转换功能
            "MP3 → WAV": self.mp3_to_wav,
            "WAV → MP3": self.wav_to_mp3,
            "MP3 → FLAC": self.mp3_to_flac,
            "FLAC → MP3": self.flac_to_mp3,
            "FLAC → ALAC": self.flac_to_alac,
            "ALAC → FLAC": self.alac_to_flac,
            "WAV → AIFF": self.wav_to_aiff,
            "AIFF → WAV": self.aiff_to_wav,
            "AAC → MP3": self.aac_to_mp3,
            "MP3 → AAC": self.mp3_to_aac,
            "MP4 → MP3": self.video_to_mp3,
            "MKV → MP3": self.video_to_mp3,
            "AVI → MP3": self.video_to_mp3,
            "MP4 → WAV": self.video_to_wav,
            "MKV → WAV": self.video_to_wav,
            "AVI → WAV": self.video_to_wav,
            "MP4 → FLAC": self.video_to_flac,
            "MKV → FLAC": self.video_to_flac,
            "AVI → FLAC": self.video_to_flac,
            # 视频转换功能
            "MP4 → MKV": self.mp4_to_mkv,
            "MKV → MP4": self.mkv_to_mp4,
            "MP4 → MOV": self.mp4_to_mov,
            "MOV → MP4": self.mov_to_mp4,
            "AVI → MP4": self.avi_to_mp4,
            "AVI → MKV": self.avi_to_mkv,
            "H.264 → H.265/HEVC": self.h264_to_h265,
            "H.265/HEVC → H.264": self.h265_to_h264,
            "VP9 → H.264": self.vp9_to_h264,
            "AV1 → H.264": self.av1_to_h264,
            "AV1 → H.265": self.av1_to_h265,
            "视频 → GIF": self.video_to_gif,
            "GIF → MP4": self.gif_to_mp4,
            "GIF → WebM": self.gif_to_webm,
            "4K → 1080p": self.video_4k_to_1080p,
            "1080p → 4K": self.video_1080p_to_4k,
            "视频分辨率转换": self.video_resolution_convert
        }
    
    def _setup_chinese_fonts(self):
        """设置中文字体支持"""
        try:
            if pdfmetrics and TTFont and ParagraphStyle:
                # 尝试注册系统中文字体
                import platform
                system = platform.system()
                
                font_registered = False
                
                # Windows系统字体路径
                if system == "Windows":
                    font_paths = [
                        "C:/Windows/Fonts/simsun.ttc",  # 宋体
                        "C:/Windows/Fonts/simhei.ttf",  # 黑体
                        "C:/Windows/Fonts/msyh.ttc",    # 微软雅黑
                        "C:/Windows/Fonts/simkai.ttf"   # 楷体
                    ]
                # macOS系统字体路径
                elif system == "Darwin":
                    font_paths = [
                        "/System/Library/Fonts/PingFang.ttc",
                        "/System/Library/Fonts/STHeiti Light.ttc",
                        "/System/Library/Fonts/Hiragino Sans GB.ttc"
                    ]
                # Linux系统字体路径
                else:
                    font_paths = [
                        "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
                        "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
                        "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc"
                    ]
                
                # 尝试注册字体
                for font_path in font_paths:
                    if os.path.exists(font_path):
                        try:
                            pdfmetrics.registerFont(TTFont('ChineseFont', font_path))
                            font_registered = True
                            break
                        except Exception:
                            continue
                
                # 如果没有找到系统字体，使用reportlab内置字体
                if not font_registered:
                    try:
                        # 使用reportlab内置的字体
                        from reportlab.pdfbase.cidfonts import UnicodeCIDFont
                        pdfmetrics.registerFont(UnicodeCIDFont('STSong-Light'))
                        self.chinese_font = 'STSong-Light'
                    except Exception:
                        # 最后的备用方案，使用Helvetica
                        self.chinese_font = 'Helvetica'
                else:
                    self.chinese_font = 'ChineseFont'
                    
        except Exception as e:
            print(f"字体设置失败，将使用默认字体: {str(e)}")
            self.chinese_font = 'Helvetica'
    
    def _get_chinese_styles(self):
        """获取支持中文的样式"""
        if getSampleStyleSheet and ParagraphStyle:
            styles = getSampleStyleSheet()
            
            # 创建支持中文的样式
            chinese_normal = ParagraphStyle(
                'ChineseNormal',
                parent=styles['Normal'],
                fontName=self.chinese_font,
                fontSize=12,
                leading=16
            )
            
            chinese_title = ParagraphStyle(
                'ChineseTitle',
                parent=styles['Title'],
                fontName=self.chinese_font,
                fontSize=18,
                leading=22
            )
            
            chinese_heading = ParagraphStyle(
                'ChineseHeading',
                parent=styles['Heading1'],
                fontName=self.chinese_font,
                fontSize=14,
                leading=18
            )
            
            styles.add(chinese_normal)
            styles.add(chinese_title)
            styles.add(chinese_heading)
            
            return styles
        else:
            return getSampleStyleSheet() if getSampleStyleSheet else None
    
    def convert_file(self, input_file, output_file, conversion_type, conversion_params=None):
        """执行文件转换"""
        try:
            if conversion_type in self.supported_conversions:
                converter_func = self.supported_conversions[conversion_type]
                
                # 检查是否需要传递额外参数
                if conversion_params and conversion_type in ["GIF → PNG", "GIF → WEBP", "GIF_EXTRACT_ALL_FRAMES"]:
                    # 对于GIF转换，传递帧相关参数
                    if conversion_type == "GIF → PNG":
                        frame_index = conversion_params.get('frame_index', 0)
                        return converter_func(input_file, output_file, frame_index=frame_index)
                    elif conversion_type == "GIF → WEBP":
                        extract_frame = conversion_params.get('extract_frame')
                        return converter_func(input_file, output_file, extract_frame=extract_frame)
                    elif conversion_type == "GIF_EXTRACT_ALL_FRAMES":
                        output_format = conversion_params.get('output_format', 'PNG')
                        return converter_func(input_file, output_file, output_format=output_format)
                else:
                    return converter_func(input_file, output_file)
            else:
                print(f"不支持的转换类型: {conversion_type}")
                return False
        except Exception as e:
            print(f"转换过程中出现错误: {str(e)}")
            return False
    
    def docx_to_pdf(self, input_file, output_file):
        """DOCX转PDF"""
        try:
            if docx2pdf_convert:
                docx2pdf_convert(input_file, output_file)
                return True
            elif Document and SimpleDocTemplate:
                # 使用python-docx读取内容，reportlab生成PDF
                doc = Document(input_file)
                
                # 创建PDF文档
                pdf_doc = SimpleDocTemplate(output_file, pagesize=A4)
                styles = self._get_chinese_styles()
                story = []
                
                # 提取文档内容
                for paragraph in doc.paragraphs:
                    if paragraph.text.strip():
                        p = Paragraph(paragraph.text, styles['ChineseNormal'])
                        story.append(p)
                        story.append(Spacer(1, 12))
                
                # 构建PDF
                pdf_doc.build(story)
                return True
            else:
                print("缺少必要的库：python-docx 和 reportlab")
                return False
        except Exception as e:
            print(f"DOCX转PDF失败: {str(e)}")
            return False
    
    def docx_to_odt(self, input_file, output_file):
        """DOCX转ODT"""
        try:
            if Document:
                # 读取DOCX文档
                doc = Document(input_file)
                
                # 创建ODT格式的XML内容
                odt_content = self._create_odt_content(doc)
                
                # 创建ODT文件（实际上是ZIP格式）
                if zipfile:
                    with zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED) as odt_zip:
                        # 添加必要的ODT文件结构
                        odt_zip.writestr('mimetype', 'application/vnd.oasis.opendocument.text')
                        odt_zip.writestr('content.xml', odt_content)
                        odt_zip.writestr('META-INF/manifest.xml', self._get_odt_manifest())
                        odt_zip.writestr('styles.xml', self._get_odt_styles())
                    return True
                else:
                    print("缺少zipfile库")
                    return False
            else:
                print("缺少python-docx库")
                return False
        except Exception as e:
            print(f"DOCX转ODT失败: {str(e)}")
            return False
    
    def xlsx_to_pdf(self, input_file, output_file):
        """XLSX转PDF"""
        try:
            if pd and SimpleDocTemplate:
                # 使用pandas读取Excel文件
                df = pd.read_excel(input_file)
                
                # 创建PDF文档
                pdf_doc = SimpleDocTemplate(output_file, pagesize=A4)
                styles = self._get_chinese_styles()
                story = []
                
                # 添加标题
                title = Paragraph(f"Excel转换: {os.path.basename(input_file)}", styles['ChineseTitle'])
                story.append(title)
                story.append(Spacer(1, 20))
                
                # 将DataFrame转换为HTML表格，然后转换为PDF段落
                html_table = df.to_html(index=False, escape=False)
                # 简化处理：将每行数据作为段落添加
                for index, row in df.iterrows():
                    row_text = " | ".join([str(val) for val in row.values])
                    p = Paragraph(row_text, styles['ChineseNormal'])
                    story.append(p)
                    story.append(Spacer(1, 6))
                
                # 构建PDF
                pdf_doc.build(story)
                return True
            else:
                print("缺少必要的库：pandas 和 reportlab")
                return False
        except Exception as e:
            print(f"XLSX转PDF失败: {str(e)}")
            return False
    
    def xlsx_to_ods(self, input_file, output_file):
        """XLSX转ODS"""
        try:
            if pd:
                # 读取Excel文件
                df = pd.read_excel(input_file)
                
                # 创建ODS格式的XML内容
                ods_content = self._create_ods_content(df)
                
                # 创建ODS文件（实际上是ZIP格式）
                if zipfile:
                    with zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED) as ods_zip:
                        # 添加必要的ODS文件结构
                        ods_zip.writestr('mimetype', 'application/vnd.oasis.opendocument.spreadsheet')
                        ods_zip.writestr('content.xml', ods_content)
                        ods_zip.writestr('META-INF/manifest.xml', self._get_ods_manifest())
                        ods_zip.writestr('styles.xml', self._get_ods_styles())
                    return True
                else:
                    print("缺少zipfile库")
                    return False
            else:
                print("缺少pandas库")
                return False
        except Exception as e:
            print(f"XLSX转ODS失败: {str(e)}")
            return False
    
    def pptx_to_pdf(self, input_file, output_file):
        """PPTX转PDF"""
        try:
            if Presentation and SimpleDocTemplate:
                # 读取PowerPoint文件
                prs = Presentation(input_file)
                
                # 创建PDF文档
                pdf_doc = SimpleDocTemplate(output_file, pagesize=A4)
                styles = self._get_chinese_styles()
                story = []
                
                # 添加标题
                title = Paragraph(f"PowerPoint转换: {os.path.basename(input_file)}", styles['ChineseTitle'])
                story.append(title)
                story.append(Spacer(1, 20))
                
                # 处理每个幻灯片
                for i, slide in enumerate(prs.slides):
                    # 添加幻灯片标题
                    slide_title = Paragraph(f"幻灯片 {i+1}", styles['ChineseHeading'])
                    story.append(slide_title)
                    story.append(Spacer(1, 12))
                    
                    # 提取幻灯片文本内容
                    for shape in slide.shapes:
                        if hasattr(shape, "text") and shape.text.strip():
                            p = Paragraph(shape.text, styles['ChineseNormal'])
                            story.append(p)
                            story.append(Spacer(1, 6))
                    
                    story.append(Spacer(1, 20))
                
                # 构建PDF
                pdf_doc.build(story)
                return True
            else:
                print("缺少必要的库：python-pptx 和 reportlab")
                return False
        except Exception as e:
            print(f"PPTX转PDF失败: {str(e)}")
            return False
    
    def pptx_to_odp(self, input_file, output_file):
        """PPTX转ODP"""
        try:
            if Presentation:
                # 读取PowerPoint文件
                prs = Presentation(input_file)
                
                # 创建ODP格式的XML内容
                odp_content = self._create_odp_content(prs)
                
                # 创建ODP文件（实际上是ZIP格式）
                if zipfile:
                    with zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED) as odp_zip:
                        # 添加必要的ODP文件结构
                        odp_zip.writestr('mimetype', 'application/vnd.oasis.opendocument.presentation')
                        odp_zip.writestr('content.xml', odp_content)
                        odp_zip.writestr('META-INF/manifest.xml', self._get_odp_manifest())
                        odp_zip.writestr('styles.xml', self._get_odp_styles())
                    return True
                else:
                    print("缺少zipfile库")
                    return False
            else:
                print("缺少python-pptx库")
                return False
        except Exception as e:
            print(f"PPTX转ODP失败: {str(e)}")
            return False
    
    def pdf_to_txt(self, input_file, output_file):
        """PDF转TXT"""
        try:
            if PyPDF2:
                with open(input_file, 'rb') as file:
                    pdf_reader = PyPDF2.PdfReader(file)
                    text = ""
                    for page in pdf_reader.pages:
                        text += page.extract_text() + "\n"
                
                with open(output_file, 'w', encoding='utf-8') as txt_file:
                    txt_file.write(text)
                return True
            else:
                # 使用pdftotext命令行工具
                result = subprocess.run(
                    ['pdftotext', input_file, output_file],
                    capture_output=True, text=True
                )
                return result.returncode == 0
        except Exception as e:
            print(f"PDF转TXT失败: {str(e)}")
            return False
    
    def rtf_to_docx(self, input_file, output_file):
        """RTF转DOCX"""
        try:
            if Document:
                # 读取RTF文件内容
                rtf_text = self._extract_rtf_text(input_file)
                
                # 创建新的DOCX文档
                doc = Document()
                
                # 将RTF文本按行添加到DOCX
                for line in rtf_text.split('\n'):
                    if line.strip():
                        doc.add_paragraph(line.strip())
                
                # 保存DOCX文件
                doc.save(output_file)
                return True
            else:
                print("缺少python-docx库")
                return False
        except Exception as e:
            print(f"RTF转DOCX失败: {str(e)}")
            return False
    
    def rtf_to_txt(self, input_file, output_file):
        """RTF转TXT"""
        try:
            # 提取RTF文本内容
            rtf_text = self._extract_rtf_text(input_file)
            
            # 保存为TXT文件
            with open(output_file, 'w', encoding='utf-8') as txt_file:
                txt_file.write(rtf_text)
            return True
        except Exception as e:
            print(f"RTF转TXT失败: {str(e)}")
            return False
    
    def epub_to_mobi(self, input_file, output_file):
        """EPUB转MOBI"""
        try:
            if epub:
                # 读取EPUB文件
                book = epub.read_epub(input_file)
                
                # 提取文本内容
                content = self._extract_epub_content(book)
                
                # 创建简化的MOBI格式（实际上是文本文件）
                # 注意：真正的MOBI格式非常复杂，这里提供基本转换
                with open(output_file, 'w', encoding='utf-8') as mobi_file:
                    mobi_file.write(content)
                
                print("注意：生成的是简化的MOBI格式（文本文件）")
                return True
            else:
                print("缺少ebooklib库")
                return False
        except Exception as e:
            print(f"EPUB转MOBI失败: {str(e)}")
            return False
    
    def epub_to_pdf(self, input_file, output_file):
        """EPUB转PDF"""
        try:
            if epub and SimpleDocTemplate:
                # 读取EPUB文件
                book = epub.read_epub(input_file)
                
                # 提取文本内容
                content = self._extract_epub_content(book)
                
                # 创建PDF文档
                pdf_doc = SimpleDocTemplate(output_file, pagesize=A4)
                styles = self._get_chinese_styles()
                story = []
                
                # 添加标题
                title = Paragraph(f"EPUB转换: {os.path.basename(input_file)}", styles['ChineseTitle'])
                story.append(title)
                story.append(Spacer(1, 20))
                
                # 添加内容
                for line in content.split('\n'):
                    if line.strip():
                        p = Paragraph(line.strip(), styles['ChineseNormal'])
                        story.append(p)
                        story.append(Spacer(1, 6))
                
                # 构建PDF
                pdf_doc.build(story)
                return True
            else:
                print("缺少必要的库：ebooklib 和 reportlab")
                return False
        except Exception as e:
            print(f"EPUB转PDF失败: {str(e)}")
            return False
    
    def mobi_to_epub(self, input_file, output_file):
        """MOBI转EPUB"""
        try:
            # MOBI格式解析比较复杂，这里提供基本实现
            print("MOBI转EPUB功能暂时不可用（需要复杂的MOBI解析器）")
            return False
        except Exception as e:
            print(f"MOBI转EPUB失败: {str(e)}")
            return False
    
    def mobi_to_pdf(self, input_file, output_file):
        """MOBI转PDF"""
        try:
            # MOBI格式解析比较复杂，这里提供基本实现
            print("MOBI转PDF功能暂时不可用（需要复杂的MOBI解析器）")
            return False
        except Exception as e:
            print(f"MOBI转PDF失败: {str(e)}")
            return False
    
    def azw3_to_epub(self, input_file, output_file):
        """AZW3转EPUB"""
        try:
            # AZW3格式解析比较复杂，这里提供基本实现
            print("AZW3转EPUB功能暂时不可用（需要复杂的AZW3解析器）")
            return False
        except Exception as e:
            print(f"AZW3转EPUB失败: {str(e)}")
            return False
    
    def html_to_pdf(self, input_file, output_file):
        """HTML转PDF"""
        try:
            # 首先尝试使用weasyprint
            if HTML:
                try:
                    html_doc = HTML(filename=input_file)
                    html_doc.write_pdf(output_file)
                    return True
                except Exception as e:
                    print(f"weasyprint转换失败，使用备用方案: {str(e)}")
                    # 继续使用备用方案
            
            # 备用方案：使用reportlab创建PDF
            if SimpleDocTemplate:
                with open(input_file, 'r', encoding='utf-8') as html_file:
                    html_content = html_file.read()
                
                # 改进的HTML标签清理和格式化
                import re
                
                # 提取标题
                title_match = re.search(r'<title[^>]*>([^<]+)</title>', html_content, re.IGNORECASE)
                title = title_match.group(1) if title_match else "HTML转PDF"
                
                # 提取和格式化内容
                # 处理段落
                paragraphs = re.findall(r'<p[^>]*>([^<]+)</p>', html_content, re.IGNORECASE)
                
                # 处理标题
                headers = re.findall(r'<h[1-6][^>]*>([^<]+)</h[1-6]>', html_content, re.IGNORECASE)
                
                # 如果没有找到段落和标题，则清理所有HTML标签
                if not paragraphs and not headers:
                    text_content = re.sub(r'<[^>]+>', '', html_content)
                    text_content = text_content.replace('&nbsp;', ' ').replace('&amp;', '&')
                    text_content = text_content.replace('&lt;', '<').replace('&gt;', '>')
                    paragraphs = [p.strip() for p in text_content.split('\n') if p.strip()]
                
                # 创建PDF文档
                pdf_doc = SimpleDocTemplate(output_file, pagesize=A4)
                styles = self._get_chinese_styles()
                story = []
                
                # 添加标题
                title_para = Paragraph(title, styles['ChineseTitle'])
                story.append(title_para)
                story.append(Spacer(1, 20))
                
                # 添加标题内容
                for header in headers:
                    h = Paragraph(header, styles['ChineseHeading'])
                    story.append(h)
                    story.append(Spacer(1, 12))
                
                # 添加段落内容
                for para in paragraphs:
                    if para.strip():
                        p = Paragraph(para.strip(), styles['ChineseNormal'])
                        story.append(p)
                        story.append(Spacer(1, 6))
                
                # 构建PDF
                pdf_doc.build(story)
                return True
            else:
                print("缺少必要的库：weasyprint 或 reportlab")
                return False
        except Exception as e:
            print(f"HTML转PDF失败: {str(e)}")
            return False
    
    def markdown_to_html(self, input_file, output_file):
        """Markdown转HTML"""
        try:
            if markdown:
                with open(input_file, 'r', encoding='utf-8') as md_file:
                    md_content = md_file.read()
                
                html_content = markdown.markdown(md_content)
                
                # 添加基本的HTML结构
                full_html = f"""
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Converted from Markdown</title>
    <style>
        body {{ font-family: Arial, sans-serif; margin: 40px; }}
        pre {{ background-color: #f4f4f4; padding: 10px; border-radius: 5px; }}
        code {{ background-color: #f4f4f4; padding: 2px 4px; border-radius: 3px; }}
    </style>
</head>
<body>
{html_content}
</body>
</html>
                """
                
                with open(output_file, 'w', encoding='utf-8') as html_file:
                    html_file.write(full_html)
                return True
            else:
                print("缺少markdown库")
                return False
        except Exception as e:
            print(f"Markdown转HTML失败: {str(e)}")
            return False
    
    def markdown_to_docx(self, input_file, output_file):
        """Markdown转DOCX"""
        try:
            if markdown and Document:
                # 读取Markdown文件
                with open(input_file, 'r', encoding='utf-8') as md_file:
                    md_content = md_file.read()
                
                # 转换为HTML
                html_content = markdown.markdown(md_content)
                
                # 创建DOCX文档
                doc = Document()
                
                # 简单的HTML到DOCX转换
                import re
                # 移除HTML标签，提取文本
                text_content = re.sub(r'<[^>]+>', '', html_content)
                text_content = text_content.replace('&nbsp;', ' ').replace('&amp;', '&')
                
                # 按行添加到文档
                for line in text_content.split('\n'):
                    if line.strip():
                        doc.add_paragraph(line.strip())
                
                doc.save(output_file)
                return True
            else:
                print("缺少必要的库：markdown 和 python-docx")
                return False
        except Exception as e:
            print(f"Markdown转DOCX失败: {str(e)}")
            return False
    
    def markdown_to_pdf(self, input_file, output_file):
        """Markdown转PDF"""
        try:
            # 先转换为HTML，再转换为PDF
            temp_html = tempfile.mktemp(suffix='.html')
            if self.markdown_to_html(input_file, temp_html):
                result = self.html_to_pdf(temp_html, output_file)
                os.unlink(temp_html)
                return result
            return False
        except Exception as e:
            print(f"Markdown转PDF失败: {str(e)}")
            return False
    
    def _extract_rtf_text(self, rtf_file):
        """提取RTF文件的文本内容"""
        try:
            if rtf_to_text:
                # 使用striprtf库进行专业的RTF解析
                with open(rtf_file, 'r', encoding='utf-8') as file:
                    rtf_content = file.read()
                return rtf_to_text(rtf_content)
            else:
                # 备用方案：简单的RTF解析
                with open(rtf_file, 'r', encoding='utf-8') as file:
                    rtf_content = file.read()
                
                # 简单的RTF解析（移除RTF控制字符）
                import re
                # 移除RTF控制字符
                text = re.sub(r'\\[a-z]+\d*\s?', '', rtf_content)
                text = re.sub(r'[{}]', '', text)
                text = re.sub(r'\\[^a-z]', '', text)
                
                return text.strip()
        except UnicodeDecodeError:
            # 尝试其他编码
            try:
                with open(rtf_file, 'r', encoding='latin-1') as file:
                    rtf_content = file.read()
                if rtf_to_text:
                    return rtf_to_text(rtf_content)
                else:
                    import re
                    text = re.sub(r'\\[a-z]+\d*\s?', '', rtf_content)
                    text = re.sub(r'[{}]', '', text)
                    text = re.sub(r'\\[^a-z]', '', text)
                    return text.strip()
            except Exception:
                return "无法解析RTF文件内容"
    
    def _extract_epub_content(self, book):
        """提取EPUB文件的文本内容"""
        content = ""
        try:
            for item in book.get_items():
                if item.get_type() == epub.EpubItem.DOCUMENT:
                    # 解析HTML内容
                    html_content = item.get_content().decode('utf-8')
                    import re
                    text = re.sub(r'<[^>]+>', '', html_content)
                    text = text.replace('&nbsp;', ' ').replace('&amp;', '&')
                    content += text + "\n"
        except Exception as e:
            content = f"无法解析EPUB内容: {str(e)}"
        return content
    
    def _create_odt_content(self, doc):
        """创建ODT格式的content.xml"""
        content = '''<?xml version="1.0" encoding="UTF-8"?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">
<office:body>
<office:text>
'''
        
        for paragraph in doc.paragraphs:
            if paragraph.text.strip():
                content += f'<text:p>{paragraph.text}</text:p>\n'
        
        content += '''</office:text>
</office:body>
</office:document-content>'''
        return content
    
    def _create_ods_content(self, df):
        """创建ODS格式的content.xml"""
        content = '''<?xml version="1.0" encoding="UTF-8"?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0">
<office:body>
<office:spreadsheet>
<table:table table:name="Sheet1">
'''
        
        # 添加表头
        content += '<table:table-row>\n'
        for col in df.columns:
            content += f'<table:table-cell><text:p>{col}</text:p></table:table-cell>\n'
        content += '</table:table-row>\n'
        
        # 添加数据行
        for _, row in df.iterrows():
            content += '<table:table-row>\n'
            for val in row.values:
                content += f'<table:table-cell><text:p>{val}</text:p></table:table-cell>\n'
            content += '</table:table-row>\n'
        
        content += '''</table:table>
</office:spreadsheet>
</office:body>
</office:document-content>'''
        return content
    
    def _create_odp_content(self, prs):
        """创建ODP格式的content.xml"""
        content = '''<?xml version="1.0" encoding="UTF-8"?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0">
<office:body>
<office:presentation>
'''
        
        for i, slide in enumerate(prs.slides):
            content += f'<draw:page draw:name="slide{i+1}">\n'
            for shape in slide.shapes:
                if hasattr(shape, "text") and shape.text.strip():
                    content += f'<draw:text-box><text:p>{shape.text}</text:p></draw:text-box>\n'
            content += '</draw:page>\n'
        
        content += '''</office:presentation>
</office:body>
</office:document-content>'''
        return content
    
    def _get_odt_manifest(self):
        """获取ODT的manifest.xml"""
        return '''<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">
<manifest:file-entry manifest:full-path="/" manifest:media-type="application/vnd.oasis.opendocument.text"/>
<manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>
<manifest:file-entry manifest:full-path="styles.xml" manifest:media-type="text/xml"/>
</manifest:manifest>'''
    
    def _get_ods_manifest(self):
        """获取ODS的manifest.xml"""
        return '''<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">
<manifest:file-entry manifest:full-path="/" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>
<manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>
<manifest:file-entry manifest:full-path="styles.xml" manifest:media-type="text/xml"/>
</manifest:manifest>'''
    
    def _get_odp_manifest(self):
        """获取ODP的manifest.xml"""
        return '''<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">
<manifest:file-entry manifest:full-path="/" manifest:media-type="application/vnd.oasis.opendocument.presentation"/>
<manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>
<manifest:file-entry manifest:full-path="styles.xml" manifest:media-type="text/xml"/>
</manifest:manifest>'''
    
    def _get_odt_styles(self):
        """获取ODT的styles.xml"""
        return '''<?xml version="1.0" encoding="UTF-8"?>
<office:document-styles xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0">
<office:styles>
<style:default-style style:family="paragraph"/>
</office:styles>
</office:document-styles>'''
    
    def _get_ods_styles(self):
        """获取ODS的styles.xml"""
        return '''<?xml version="1.0" encoding="UTF-8"?>
<office:document-styles xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0">
<office:styles>
<style:default-style style:family="table-cell"/>
</office:styles>
</office:document-styles>'''
    
    def _get_odp_styles(self):
        """获取ODP的styles.xml"""
        return '''<?xml version="1.0" encoding="UTF-8"?>
<office:document-styles xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0">
<office:styles>
<style:default-style style:family="graphic"/>
</office:styles>
</office:document-styles>'''
    
    def check_dependencies(self):
        """检查Python库依赖项"""
        missing = []
        required_packages = {
            'python-docx': 'python-docx',
            'openpyxl': 'openpyxl', 
            'python-pptx': 'python-pptx',
            'reportlab': 'reportlab',
            'pandas': 'pandas',
            'PyPDF2': 'PyPDF2',
            'fpdf': 'fpdf2',
            'markdown': 'markdown',
            'weasyprint': 'weasyprint',
            'ebooklib': 'ebooklib',
            'striprtf': 'striprtf'
        }
        
        for package_name, import_name in required_packages.items():
            try:
                __import__(import_name.replace('-', '_'))
            except ImportError:
                missing.append(package_name)
        
        return missing
    
    # ==================== 图像转换功能 ====================
    
    def jpg_to_png(self, input_file, output_file):
        """JPG/JPEG转PNG"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    # 转换为RGB模式（PNG支持透明度，但JPG不支持）
                    if img.mode in ('RGBA', 'LA'):
                        background = Image.new('RGB', img.size, (255, 255, 255))
                        background.paste(img, mask=img.split()[-1] if img.mode == 'RGBA' else None)
                        img = background
                    elif img.mode != 'RGB':
                        img = img.convert('RGB')
                    
                    img.save(output_file, 'PNG')
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"JPG转PNG失败: {str(e)}")
            return False
    
    def jpg_to_webp(self, input_file, output_file):
        """JPG/JPEG转WEBP"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    img.save(output_file, 'WEBP', quality=85)
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"JPG转WEBP失败: {str(e)}")
            return False
    
    def png_to_jpg(self, input_file, output_file):
        """PNG转JPG/JPEG"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    # PNG可能有透明度，需要转换为RGB
                    if img.mode in ('RGBA', 'LA'):
                        background = Image.new('RGB', img.size, (255, 255, 255))
                        if img.mode == 'RGBA':
                            background.paste(img, mask=img.split()[-1])
                        else:
                            background.paste(img)
                        img = background
                    elif img.mode != 'RGB':
                        img = img.convert('RGB')
                    
                    img.save(output_file, 'JPEG', quality=95)
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"PNG转JPG失败: {str(e)}")
            return False
    
    def png_to_webp(self, input_file, output_file):
        """PNG转WEBP"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    img.save(output_file, 'WEBP', quality=85, lossless=True)
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"PNG转WEBP失败: {str(e)}")
            return False
    
    def webp_to_jpg(self, input_file, output_file):
        """WEBP转JPG/JPEG"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    if img.mode in ('RGBA', 'LA'):
                        background = Image.new('RGB', img.size, (255, 255, 255))
                        if img.mode == 'RGBA':
                            background.paste(img, mask=img.split()[-1])
                        else:
                            background.paste(img)
                        img = background
                    elif img.mode != 'RGB':
                        img = img.convert('RGB')
                    
                    img.save(output_file, 'JPEG', quality=95)
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"WEBP转JPG失败: {str(e)}")
            return False
    
    def webp_to_png(self, input_file, output_file):
        """WEBP转PNG"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    img.save(output_file, 'PNG')
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"WEBP转PNG失败: {str(e)}")
            return False
    
    def gif_to_png(self, input_file, output_file, frame_index=0):
        """GIF转PNG（提取指定帧）
        
        Args:
            input_file: 输入GIF文件路径
            output_file: 输出PNG文件路径
            frame_index: 要提取的帧索引（默认为0，即第一帧）
        """
        try:
            if Image and ImageSequence:
                with Image.open(input_file) as img:
                    # 如果是动画GIF
                    if hasattr(img, 'is_animated') and img.is_animated:
                        frame_count = getattr(img, 'n_frames', 1)
                        
                        # 验证帧索引
                        if frame_index >= frame_count:
                            print(f"帧索引超出范围。GIF共有{frame_count}帧，请选择0-{frame_count-1}")
                            return False
                        
                        img.seek(frame_index)  # 跳转到指定帧
                    
                    # 转换为RGBA模式以保持透明度
                    if img.mode != 'RGBA':
                        img = img.convert('RGBA')
                    
                    img.save(output_file, 'PNG')
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"GIF转PNG失败: {str(e)}")
            return False
    
    def gif_to_webp(self, input_file, output_file, extract_frame=None):
        """GIF转WEBP（保持动画或提取指定帧）
        
        Args:
            input_file: 输入GIF文件路径
            output_file: 输出WEBP文件路径
            extract_frame: 要提取的帧索引（None表示保持动画，数字表示提取指定帧）
        """
        try:
            if Image:
                with Image.open(input_file) as img:
                    # 如果指定了帧索引，提取单帧
                    if extract_frame is not None:
                        if hasattr(img, 'is_animated') and img.is_animated:
                            frame_count = getattr(img, 'n_frames', 1)
                            
                            # 验证帧索引
                            if extract_frame >= frame_count:
                                print(f"帧索引超出范围。GIF共有{frame_count}帧，请选择0-{frame_count-1}")
                                return False
                            
                            img.seek(extract_frame)  # 跳转到指定帧
                        
                        # 保存单帧
                        img.save(output_file, 'WEBP', quality=85)
                    else:
                        # 保持动画
                        img.save(output_file, 'WEBP', save_all=True, duration=img.info.get('duration', 100))
                    
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"GIF转WEBP失败: {str(e)}")
            return False
    
    def get_gif_frame_info(self, input_file):
        """获取GIF动图的帧信息
        
        Args:
            input_file: 输入GIF文件路径
            
        Returns:
            dict: 包含帧数、持续时间等信息的字典
        """
        try:
            if Image:
                with Image.open(input_file) as img:
                    info = {
                        'is_animated': getattr(img, 'is_animated', False),
                        'frame_count': getattr(img, 'n_frames', 1),
                        'duration': img.info.get('duration', 100),
                        'size': img.size,
                        'mode': img.mode
                    }
                    
                    # 如果是动画，获取每帧的持续时间
                    if info['is_animated']:
                        frame_durations = []
                        for frame_index in range(info['frame_count']):
                            img.seek(frame_index)
                            frame_durations.append(img.info.get('duration', 100))
                        info['frame_durations'] = frame_durations
                    
                    return info
            else:
                print("缺少PIL/Pillow库")
                return None
        except Exception as e:
            print(f"获取GIF信息失败: {str(e)}")
            return None
    
    def gif_extract_all_frames(self, input_file, output_dir, output_format='PNG'):
        """提取GIF的所有帧为单独文件
        
        Args:
            input_file: 输入GIF文件路径
            output_dir: 输出目录
            output_format: 输出格式（PNG或JPG）
            
        Returns:
            list: 输出文件路径列表
        """
        try:
            if Image and ImageSequence:
                import os
                os.makedirs(output_dir, exist_ok=True)
                
                output_files = []
                base_name = os.path.splitext(os.path.basename(input_file))[0]
                
                with Image.open(input_file) as img:
                    if hasattr(img, 'is_animated') and img.is_animated:
                        frame_count = getattr(img, 'n_frames', 1)
                        
                        for frame_index in range(frame_count):
                            img.seek(frame_index)
                            
                            # 转换模式
                            frame_img = img.copy()
                            if output_format.upper() == 'JPG' or output_format.upper() == 'JPEG':
                                if frame_img.mode in ('RGBA', 'LA'):
                                    background = Image.new('RGB', frame_img.size, (255, 255, 255))
                                    if frame_img.mode == 'RGBA':
                                        background.paste(frame_img, mask=frame_img.split()[-1])
                                    else:
                                        background.paste(frame_img)
                                    frame_img = background
                                elif frame_img.mode != 'RGB':
                                    frame_img = frame_img.convert('RGB')
                            elif output_format.upper() == 'PNG':
                                if frame_img.mode != 'RGBA':
                                    frame_img = frame_img.convert('RGBA')
                            
                            # 保存帧
                            output_file = os.path.join(output_dir, f"{base_name}_frame_{frame_index:03d}.{output_format.lower()}")
                            frame_img.save(output_file, output_format.upper())
                            output_files.append(output_file)
                    else:
                        # 非动画GIF，只保存一帧
                        frame_img = img.copy()
                        if output_format.upper() == 'JPG' or output_format.upper() == 'JPEG':
                            if frame_img.mode in ('RGBA', 'LA'):
                                background = Image.new('RGB', frame_img.size, (255, 255, 255))
                                if frame_img.mode == 'RGBA':
                                    background.paste(frame_img, mask=frame_img.split()[-1])
                                else:
                                    background.paste(frame_img)
                                frame_img = background
                            elif frame_img.mode != 'RGB':
                                frame_img = frame_img.convert('RGB')
                        elif output_format.upper() == 'PNG':
                            if frame_img.mode != 'RGBA':
                                frame_img = frame_img.convert('RGBA')
                        
                        output_file = os.path.join(output_dir, f"{base_name}.{output_format.lower()}")
                        frame_img.save(output_file, output_format.upper())
                        output_files.append(output_file)
                
                return output_files
            else:
                print("缺少PIL/Pillow库")
                return []
        except Exception as e:
            print(f"提取GIF帧失败: {str(e)}")
            return []
    
    def bmp_to_jpg(self, input_file, output_file):
        """BMP转JPG"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    if img.mode != 'RGB':
                        img = img.convert('RGB')
                    img.save(output_file, 'JPEG', quality=95)
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"BMP转JPG失败: {str(e)}")
            return False
    
    def bmp_to_png(self, input_file, output_file):
        """BMP转PNG"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    img.save(output_file, 'PNG')
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"BMP转PNG失败: {str(e)}")
            return False
    
    def tiff_to_jpg(self, input_file, output_file):
        """TIFF转JPG"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    if img.mode in ('RGBA', 'LA'):
                        background = Image.new('RGB', img.size, (255, 255, 255))
                        if img.mode == 'RGBA':
                            background.paste(img, mask=img.split()[-1])
                        else:
                            background.paste(img)
                        img = background
                    elif img.mode != 'RGB':
                        img = img.convert('RGB')
                    
                    img.save(output_file, 'JPEG', quality=95)
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"TIFF转JPG失败: {str(e)}")
            return False
    
    def tiff_to_png(self, input_file, output_file):
        """TIFF转PNG"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    img.save(output_file, 'PNG')
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"TIFF转PNG失败: {str(e)}")
            return False
    
    def raw_to_jpg(self, input_file, output_file):
        """RAW转JPG"""
        try:
            if rawpy and Image:
                with rawpy.imread(input_file) as raw:
                    rgb = raw.postprocess()
                    img = Image.fromarray(rgb)
                    img.save(output_file, 'JPEG', quality=95)
                    return True
            else:
                print("缺少rawpy库")
                return False
        except Exception as e:
            print(f"RAW转JPG失败: {str(e)}")
            return False
    
    def raw_to_png(self, input_file, output_file):
        """RAW转PNG"""
        try:
            if rawpy and Image:
                with rawpy.imread(input_file) as raw:
                    rgb = raw.postprocess()
                    img = Image.fromarray(rgb)
                    img.save(output_file, 'PNG')
                    return True
            else:
                print("缺少rawpy库")
                return False
        except Exception as e:
            print(f"RAW转PNG失败: {str(e)}")
            return False
    
    def raw_to_tiff(self, input_file, output_file):
        """RAW转TIFF"""
        try:
            if rawpy and Image:
                with rawpy.imread(input_file) as raw:
                    rgb = raw.postprocess()
                    img = Image.fromarray(rgb)
                    img.save(output_file, 'TIFF')
                    return True
            else:
                print("缺少rawpy库")
                return False
        except Exception as e:
            print(f"RAW转TIFF失败: {str(e)}")
            return False
    
    def raw_to_dng(self, input_file, output_file):
        """RAW转DNG（简化实现）"""
        try:
            # DNG转换需要专业的RAW处理库，这里提供基础实现
            print("RAW转DNG需要专业的RAW处理软件，建议使用Adobe DNG Converter")
            return False
        except Exception as e:
            print(f"RAW转DNG失败: {str(e)}")
            return False
    
    def svg_to_pdf(self, input_file, output_file):
        """SVG转PDF"""
        try:
            if cairosvg:
                cairosvg.svg2pdf(url=input_file, write_to=output_file)
                return True
            else:
                print("缺少cairosvg库")
                return False
        except Exception as e:
            print(f"SVG转PDF失败: {str(e)}")
            return False
    
    def svg_to_png(self, input_file, output_file):
        """SVG转PNG（光栅化）"""
        try:
            if cairosvg:
                cairosvg.svg2png(url=input_file, write_to=output_file)
                return True
            else:
                print("缺少cairosvg库")
                return False
        except Exception as e:
            print(f"SVG转PNG失败: {str(e)}")
            return False
    
    def svg_to_jpg(self, input_file, output_file):
        """SVG转JPG（光栅化）"""
        try:
            if cairosvg and Image:
                # 先转换为PNG，再转换为JPG
                temp_png = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
                temp_png.close()
                
                cairosvg.svg2png(url=input_file, write_to=temp_png.name)
                
                with Image.open(temp_png.name) as img:
                    if img.mode in ('RGBA', 'LA'):
                        background = Image.new('RGB', img.size, (255, 255, 255))
                        if img.mode == 'RGBA':
                            background.paste(img, mask=img.split()[-1])
                        else:
                            background.paste(img)
                        img = background
                    elif img.mode != 'RGB':
                        img = img.convert('RGB')
                    
                    img.save(output_file, 'JPEG', quality=95)
                
                os.unlink(temp_png.name)
                return True
            else:
                print("缺少cairosvg或PIL/Pillow库")
                return False
        except Exception as e:
            print(f"SVG转JPG失败: {str(e)}")
            return False
    
    def pdf_to_jpg(self, input_file, output_file):
        """PDF转JPG（提取页面为图像）"""
        try:
            if convert_from_path:
                pages = convert_from_path(input_file)
                if pages:
                    # 保存第一页为JPG
                    pages[0].save(output_file, 'JPEG', quality=95)
                    return True
                else:
                    print("PDF文件没有页面")
                    return False
            else:
                print("缺少pdf2image库")
                return False
        except Exception as e:
            print(f"PDF转JPG失败: {str(e)}")
            return False
    
    def pdf_to_png(self, input_file, output_file):
        """PDF转PNG（提取页面为图像）"""
        try:
            if convert_from_path:
                pages = convert_from_path(input_file)
                if pages:
                    # 保存第一页为PNG
                    pages[0].save(output_file, 'PNG')
                    return True
                else:
                    print("PDF文件没有页面")
                    return False
            else:
                print("缺少pdf2image库")
                return False
        except Exception as e:
            print(f"PDF转PNG失败: {str(e)}")
            return False
    
    def heic_to_jpg(self, input_file, output_file):
        """HEIC转JPG"""
        try:
            if Image and pillow_heif:
                with Image.open(input_file) as img:
                    if img.mode != 'RGB':
                        img = img.convert('RGB')
                    img.save(output_file, 'JPEG', quality=95)
                    return True
            else:
                print("缺少PIL/Pillow或pillow-heif库")
                return False
        except Exception as e:
            print(f"HEIC转JPG失败: {str(e)}")
            return False
    
    def heic_to_png(self, input_file, output_file):
        """HEIC转PNG"""
        try:
            if Image and pillow_heif:
                with Image.open(input_file) as img:
                    img.save(output_file, 'PNG')
                    return True
            else:
                print("缺少PIL/Pillow或pillow-heif库")
                return False
        except Exception as e:
             print(f"HEIC转PNG失败: {str(e)}")
             return False
    
    def jpg_to_svg(self, input_file, output_file):
        """JPG转SVG（矢量化）"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    width, height = img.size
                    
                    # 创建SVG内容，将图像嵌入为base64
                    import base64
                    import io
                    
                    # 将图像转换为base64
                    buffer = io.BytesIO()
                    img.save(buffer, format='JPEG')
                    img_base64 = base64.b64encode(buffer.getvalue()).decode()
                    
                    # 创建SVG内容
                    svg_content = f'''<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="{width}" height="{height}" viewBox="0 0 {width} {height}">
  <image x="0" y="0" width="{width}" height="{height}" 
         xlink:href="data:image/jpeg;base64,{img_base64}"/>
</svg>'''
                    
                    with open(output_file, 'w', encoding='utf-8') as f:
                        f.write(svg_content)
                    
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"JPG转SVG失败: {str(e)}")
            return False
    
    def png_to_svg(self, input_file, output_file):
        """PNG转SVG（矢量化）"""
        try:
            if Image:
                with Image.open(input_file) as img:
                    width, height = img.size
                    
                    # 创建SVG内容，将图像嵌入为base64
                    import base64
                    import io
                    
                    # 将图像转换为base64
                    buffer = io.BytesIO()
                    img.save(buffer, format='PNG')
                    img_base64 = base64.b64encode(buffer.getvalue()).decode()
                    
                    # 创建SVG内容
                    svg_content = f'''<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="{width}" height="{height}" viewBox="0 0 {width} {height}">
  <image x="0" y="0" width="{width}" height="{height}" 
         xlink:href="data:image/png;base64,{img_base64}"/>
</svg>'''
                    
                    with open(output_file, 'w', encoding='utf-8') as f:
                        f.write(svg_content)
                    
                    return True
            else:
                print("缺少PIL/Pillow库")
                return False
        except Exception as e:
            print(f"PNG转SVG失败: {str(e)}")
            return False
    
    # ==================== 音频转换方法 ====================
    
    def mp3_to_wav(self, input_file, output_file):
        """MP3转WAV"""
        try:
            if AudioSegment:
                audio = AudioSegment.from_mp3(input_file)
                audio.export(output_file, format="wav")
                return True
            elif librosa and sf:
                # 使用librosa和soundfile
                y, sr = librosa.load(input_file, sr=None)
                sf.write(output_file, y, sr)
                return True
            else:
                print("缺少pydub或librosa+soundfile库")
                return False
        except Exception as e:
            print(f"MP3转WAV失败: {str(e)}")
            return False
    
    def wav_to_mp3(self, input_file, output_file):
        """WAV转MP3"""
        try:
            if AudioSegment:
                audio = AudioSegment.from_wav(input_file)
                audio.export(output_file, format="mp3", bitrate="192k")
                return True
            else:
                print("缺少pydub库")
                return False
        except Exception as e:
            print(f"WAV转MP3失败: {str(e)}")
            return False
    
    def mp3_to_flac(self, input_file, output_file):
        """MP3转FLAC"""
        try:
            if AudioSegment:
                audio = AudioSegment.from_mp3(input_file)
                audio.export(output_file, format="flac")
                return True
            else:
                print("缺少pydub库")
                return False
        except Exception as e:
            print(f"MP3转FLAC失败: {str(e)}")
            return False
    
    def flac_to_mp3(self, input_file, output_file):
        """FLAC转MP3"""
        try:
            if AudioSegment:
                audio = AudioSegment.from_file(input_file, format="flac")
                audio.export(output_file, format="mp3", bitrate="192k")
                return True
            else:
                print("缺少pydub库")
                return False
        except Exception as e:
            print(f"FLAC转MP3失败: {str(e)}")
            return False
    
    def flac_to_alac(self, input_file, output_file):
        """FLAC转ALAC（Apple Lossless）"""
        try:
            if ffmpeg:
                # 使用ffmpeg进行转换
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, acodec='alac')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"FLAC转ALAC失败: {str(e)}")
            return False
    
    def alac_to_flac(self, input_file, output_file):
        """ALAC转FLAC"""
        try:
            if ffmpeg:
                # 使用ffmpeg进行转换
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, acodec='flac')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"ALAC转FLAC失败: {str(e)}")
            return False
    
    def wav_to_aiff(self, input_file, output_file):
        """WAV转AIFF"""
        try:
            if AudioSegment:
                audio = AudioSegment.from_wav(input_file)
                audio.export(output_file, format="aiff")
                return True
            else:
                print("缺少pydub库")
                return False
        except Exception as e:
            print(f"WAV转AIFF失败: {str(e)}")
            return False
    
    def aiff_to_wav(self, input_file, output_file):
        """AIFF转WAV"""
        try:
            if AudioSegment:
                audio = AudioSegment.from_file(input_file, format="aiff")
                audio.export(output_file, format="wav")
                return True
            else:
                print("缺少pydub库")
                return False
        except Exception as e:
            print(f"AIFF转WAV失败: {str(e)}")
            return False
    
    def aac_to_mp3(self, input_file, output_file):
        """AAC转MP3"""
        try:
            if AudioSegment:
                audio = AudioSegment.from_file(input_file, format="aac")
                audio.export(output_file, format="mp3", bitrate="192k")
                return True
            else:
                print("缺少pydub库")
                return False
        except Exception as e:
            print(f"AAC转MP3失败: {str(e)}")
            return False
    
    def mp3_to_aac(self, input_file, output_file):
        """MP3转AAC"""
        try:
            if AudioSegment:
                audio = AudioSegment.from_mp3(input_file)
                audio.export(output_file, format="aac", bitrate="128k")
                return True
            else:
                print("缺少pydub库")
                return False
        except Exception as e:
            print(f"MP3转AAC失败: {str(e)}")
            return False
    
    def video_to_mp3(self, input_file, output_file):
        """从视频文件提取MP3音频"""
        try:
            if AudioSegment:
                # 使用pydub从视频中提取音频
                audio = AudioSegment.from_file(input_file)
                audio.export(output_file, format="mp3", bitrate="192k")
                return True
            elif ffmpeg:
                # 使用ffmpeg提取音频
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, acodec='mp3', audio_bitrate='192k')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少pydub或ffmpeg-python库")
                return False
        except Exception as e:
            print(f"视频提取MP3失败: {str(e)}")
            return False
    
    def video_to_wav(self, input_file, output_file):
        """从视频文件提取WAV音频"""
        try:
            if AudioSegment:
                # 使用pydub从视频中提取音频
                audio = AudioSegment.from_file(input_file)
                audio.export(output_file, format="wav")
                return True
            elif ffmpeg:
                # 使用ffmpeg提取音频
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, acodec='pcm_s16le')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少pydub或ffmpeg-python库")
                return False
        except Exception as e:
            print(f"视频提取WAV失败: {str(e)}")
            return False
    
    def video_to_flac(self, input_file, output_file):
        """从视频文件提取FLAC音频"""
        try:
            if ffmpeg:
                # 使用ffmpeg提取音频并转换为FLAC
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, acodec='flac')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            elif AudioSegment:
                # 使用pydub从视频中提取音频
                audio = AudioSegment.from_file(input_file)
                audio.export(output_file, format="flac")
                return True
            else:
                print("缺少ffmpeg-python或pydub库")
                return False
        except Exception as e:
            print(f"视频提取FLAC失败: {str(e)}")
            return False
    
    # ==================== 视频转换方法 ====================
    
    def mp4_to_mkv(self, input_file, output_file):
        """MP4转MKV"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='copy', acodec='copy')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"MP4转MKV失败: {str(e)}")
            return False
    
    def mkv_to_mp4(self, input_file, output_file):
        """MKV转MP4"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='copy', acodec='copy')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"MKV转MP4失败: {str(e)}")
            return False
    
    def mp4_to_mov(self, input_file, output_file):
        """MP4转MOV"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='copy', acodec='copy')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"MP4转MOV失败: {str(e)}")
            return False
    
    def mov_to_mp4(self, input_file, output_file):
        """MOV转MP4"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='copy', acodec='copy')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"MOV转MP4失败: {str(e)}")
            return False
    
    def avi_to_mp4(self, input_file, output_file):
        """AVI转MP4"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='libx264', acodec='aac')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"AVI转MP4失败: {str(e)}")
            return False
    
    def avi_to_mkv(self, input_file, output_file):
        """AVI转MKV"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='copy', acodec='copy')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"AVI转MKV失败: {str(e)}")
            return False
    
    def h264_to_h265(self, input_file, output_file):
        """H.264转H.265/HEVC"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='libx265', acodec='copy', crf=23)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"H.264转H.265失败: {str(e)}")
            return False
    
    def h265_to_h264(self, input_file, output_file):
        """H.265/HEVC转H.264"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='libx264', acodec='copy', crf=23)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"H.265转H.264失败: {str(e)}")
            return False
    
    def vp9_to_h264(self, input_file, output_file):
        """VP9转H.264"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='libx264', acodec='copy', crf=23)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"VP9转H.264失败: {str(e)}")
            return False
    
    def av1_to_h264(self, input_file, output_file):
        """AV1转H.264"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='libx264', acodec='copy', crf=23)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"AV1转H.264失败: {str(e)}")
            return False
    
    def av1_to_h265(self, input_file, output_file):
        """AV1转H.265"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='libx265', acodec='copy', crf=23)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"AV1转H.265失败: {str(e)}")
            return False
    
    def video_to_gif(self, input_file, output_file, start_time=0, duration=10, fps=10, scale=320):
        """视频转GIF"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file, ss=start_time, t=duration)
                    .filter('fps', fps=fps)
                    .filter('scale', scale, -1)
                    .output(output_file)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"视频转GIF失败: {str(e)}")
            return False
    
    def gif_to_mp4(self, input_file, output_file):
        """GIF转MP4"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='libx264', pix_fmt='yuv420p')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"GIF转MP4失败: {str(e)}")
            return False
    
    def gif_to_webm(self, input_file, output_file):
        """GIF转WebM"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .output(output_file, vcodec='libvpx-vp9', acodec='libopus')
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"GIF转WebM失败: {str(e)}")
            return False
    
    def video_4k_to_1080p(self, input_file, output_file):
        """4K转1080p"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .filter('scale', 1920, 1080)
                    .output(output_file, vcodec='libx264', acodec='copy', crf=23)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"4K转1080p失败: {str(e)}")
            return False
    
    def video_1080p_to_4k(self, input_file, output_file):
        """1080p转4K（上采样）"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .filter('scale', 3840, 2160)
                    .output(output_file, vcodec='libx264', acodec='copy', crf=18)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"1080p转4K失败: {str(e)}")
            return False
    
    def video_resolution_convert(self, input_file, output_file, width=1920, height=1080):
        """视频分辨率转换（自定义分辨率）"""
        try:
            if ffmpeg:
                (
                    ffmpeg
                    .input(input_file)
                    .filter('scale', width, height)
                    .output(output_file, vcodec='libx264', acodec='copy', crf=23)
                    .overwrite_output()
                    .run(quiet=True)
                )
                return True
            else:
                print("缺少ffmpeg-python库")
                return False
        except Exception as e:
            print(f"视频分辨率转换失败: {str(e)}")
            return False